package ru.pb.game.data.xml.holders;

import gnu.trove.map.hash.TIntObjectHashMap;

import java.util.Collection;

import ru.pb.game.data.templates.AbstractItemTemplate;
import ru.pb.game.data.templates.ArmorTemplate;
import ru.pb.game.data.templates.CuponTemplate;
import ru.pb.game.data.templates.WeaponTemplate;
import ru.pb.game.idfactory.IdFactory;
import ru.pb.game.objects.model.items.Item;
import ru.pb.global.configs.DevelopConfig;
import ru.pb.global.data.model.ItemInfo;
import ru.pb.global.xml.holder.AbstractHolder;

public final class ItemHolder extends AbstractHolder
{
	private static ItemHolder _instance;

	private final TIntObjectHashMap<WeaponTemplate> _weaponsTemplate = new TIntObjectHashMap<WeaponTemplate>();
	private final TIntObjectHashMap<ArmorTemplate> _armorsTemplate = new TIntObjectHashMap<ArmorTemplate>();
	private final TIntObjectHashMap<CuponTemplate> _cuponsTemplate = new TIntObjectHashMap<CuponTemplate>();

	private TIntObjectHashMap<AbstractItemTemplate> _itemTable;

	public static ItemHolder getInstance()
	{
		if(_instance == null)
			_instance = new ItemHolder();
		return _instance;
	}

	private ItemHolder()
	{}

	public Item createItem(final int itemId)
	{
		final Item temp = new Item(IdFactory.getInstance().getNextId(), itemId);

		if(DevelopConfig.DEBUG)
			_log.info("ItemInfo created	itemObjId: " + temp.getObjectId() + " itemid:" + itemId);

		return temp;
	}

	public AbstractItemTemplate getTemplate(final int id)
	{
		if(id <= 0)
		{
			_log.info("Incorrect itemId : " + id, new Exception());
			return null;
		}
		return _itemTable.get(id);
	}

	private void buildFastLookTable()
	{
		_itemTable = new TIntObjectHashMap<AbstractItemTemplate>();

		for(AbstractItemTemplate a : getAllArmors())
			_itemTable.put(a.getItemId(), a);

		for(AbstractItemTemplate w : getAllWeapons())
			_itemTable.put(w.getItemId(), w);

		for(AbstractItemTemplate c : getAllCupons())
			_itemTable.put(c.getItemId(), c);
	}

	public Item createDummyItem(final int itemId)
	{
		final AbstractItemTemplate itemTemplate = getTemplate(itemId);
		if(itemTemplate == null)
			return null;
		Item temp = new Item(0, itemTemplate, new ItemInfo(itemId, itemTemplate.getItemType().ordinal(), itemTemplate.getItemSlot().ordinal()));
		if(temp.getTemplate() == null)
			_log.info("Item Template missing for Id: " + itemId);
		return temp;
	}

	public Collection<WeaponTemplate> getAllWeapons()
	{
		return _weaponsTemplate.valueCollection();
	}

	public Collection<ArmorTemplate> getAllArmors()
	{
		return _armorsTemplate.valueCollection();
	}

	public Collection<CuponTemplate> getAllCupons()
	{
		return _cuponsTemplate.valueCollection();
	}

	public void addTemplate(AbstractItemTemplate template)
	{
		if(template instanceof WeaponTemplate)
		{
			if(_weaponsTemplate.containsKey(template.getItemId()))
			{
				_log.info("Weapon Already name: " + template.getItemName() + "; num: " + template.getItemId() + "; ID: " + template.getItemId());
			}
			else
			{
				_weaponsTemplate.put(template.getItemId(), (WeaponTemplate) template);
			}
		}

		else if(template instanceof ArmorTemplate)
		{
			if(_armorsTemplate.containsKey(template.getItemId()))
			{
				_log.info("Armor Already name: " + template.getItemName() + "; num: " + template.getItemId() + "; ID: " + template.getItemId());
			}
			else
			{
				_armorsTemplate.put(template.getItemId(), (ArmorTemplate) template);
			}
		}
		else if(template instanceof CuponTemplate)
		{
			if(_cuponsTemplate.containsKey(template.getItemId()))
			{
				_log.info("Cupon Already name: " + template.getItemName() + "; num: " + template.getItemId() + "; ID: " + template.getItemId());
			}
			else
			{
				_cuponsTemplate.put(template.getItemId(), (CuponTemplate) template);
			}
		}
	}

	@Override
	public void log()
	{
		buildFastLookTable();
		info(String.format("load %d weapon(s).", _weaponsTemplate.size()));
		info(String.format("load %d armor(s).", _armorsTemplate.size()));
		info(String.format("load %d cupon(s).", _cuponsTemplate.size()));
		info(String.format("All item(s): %d.", _itemTable.size()));

		/*
		 * for(WeaponTemplate temp : _weaponsTemplate.valueCollection())
		 * {
		 * info("name: " + temp.getItemName() + "; num: " + temp.getItemNum() + "; ID: " + temp.getItemId());
		 * }
		 * for(ArmorTemplate temp : _armorsTemplate.valueCollection())
		 * {
		 * info("name: " + temp.getItemName() + "; num: " + temp.getItemNum() + "; ID: " + temp.getItemId());
		 * }
		 * for(CuponTemplate temp : _cuponsTemplate.valueCollection())
		 * {
		 * info("name: " + temp.getItemName() + "; num: " + temp.getItemNum() + "; ID: " + temp.getItemId());
		 * }
		 */
	}

	@Override
	public int size()
	{
		return 0;
	}

	@Override
	public void clear()
	{
		_weaponsTemplate.clear();
		_armorsTemplate.clear();
		_cuponsTemplate.clear();
		_itemTable.clear();
	}
}